using System;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.SharePoint;

   
//    tiago duarte custom theme stylesheet
//    for sharepoint 2010 websites
//    all templates valid
//    v1.00
//    5 January 2013
//    http://ftduarte.blogspot.com
//

//using System;
//using System.Runtime.InteropServices;
//using System.Security.Permissions;
//using Microsoft.SharePoint;
//using Microsoft.SharePoint.Security;
//using System.Linq;
//using System.Xml.Linq;

namespace CustomTheme.Features.Feature1
{
    /// <summary>
    /// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
    /// </summary>
    /// <remarks>
    /// The GUID attached to this class may be used during packaging and should not be modified.
    /// </remarks>

    [Guid("9481e2b1-ddcb-4582-93e1-308e152144a6")]
    public class Feature1EventReceiver : SPFeatureReceiver
    {
        // The SharePoint elements file namespace
        private static readonly System.Xml.Linq.XNamespace WS = "http://schemas.microsoft.com/sharepoint/";
        private static readonly string customlistname = "CustomThemeList"; 
        private static readonly string[] masterpages = {"Custom.14.master", "Custom.Meetings.master", "Custom.Search.master"};

        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            //notice:
            //- list CustomThemeList is created before module provisioning
            //- theme resources folder

            using (SPWeb web = (SPWeb)properties.Feature.Parent)
            {
                string relativeUrl = web.ServerRelativeUrl;
                if (!(relativeUrl.EndsWith("/")))
                {
                    relativeUrl += "/";
                }

                //check in all files in list
                CheckinCustomList(web, customlistname);

                //check in master pages
                foreach (string masterpage in masterpages)
                {
                    PublishFile(web.GetFile(relativeUrl + "_catalogs/masterpage/" + masterpage));
                }

                //apply masters to current web site
                applyMaster(web, true, relativeUrl);

                //apply masters to all other web sites, if this is root
                if (web.IsRootWeb)
                {
                    SPWebCollection webs = web.Site.AllWebs;
                    foreach (SPWeb subWeb in webs)
                    {
                        if (!subWeb.IsRootWeb)
                        {
                            applyMaster(subWeb, true, relativeUrl);
                            subWeb.Update();
                        }
                    }
                }

                //update this web
                web.Update();
            }
        }

        
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            using (SPWeb web = (SPWeb)properties.Feature.Parent)
            {                
                string relativeUrl = web.ServerRelativeUrl;
                if (!(relativeUrl.EndsWith("/")))
                {
                    relativeUrl += "/";
                }

                //check in and delete custom list
                RemoveList(web, customlistname);
                
                //apply default masters to this web
                applyMaster(web, false, relativeUrl);

                //apply default masters to all other webs
                if (web.IsRootWeb)
                {
                    SPWebCollection webs = web.Site.AllWebs;
                    foreach (SPWeb subWeb in webs)
                    {
                        if (!subWeb.IsRootWeb)
                        {
                            relativeUrl = subWeb.ServerRelativeUrl;
                            if (!(relativeUrl.EndsWith("/")))
                            {
                                relativeUrl += "/";
                            }

                            applyMaster(subWeb, false, relativeUrl);
                            subWeb.Update();
                        }
                    }
                }

                //make sure references are gone
                web.Update();

                //check in and remove master pages
                foreach (string masterpage in masterpages)
                {
                    SPFile masterFile = web.GetFile(relativeUrl + "_catalogs/masterpage/" + masterpage);
                    if (masterFile.Exists)
                    {
                        PublishFile(masterFile);
                        try
                        {
                            masterFile.Delete();
                        }
                        catch 
                        {
                        }
                    }
                }
                web.Update();
            }
        }

        /// <summary>
        /// This method applies custom or default master page per web template
        /// </summary>
        public static void applyMaster(SPWeb web, bool activating, string relativeUrl)
        {
            string siteMaster;//site master = custom master page = front end
            string systemMaster;//system master = default master page = admin

            if (activating)
            {
                siteMaster = relativeUrl + "_catalogs/masterpage/" + masterpages[0];
                systemMaster = relativeUrl + "_catalogs/masterpage/" + masterpages[0];

                //mettings - set both masters
                if (web.WebTemplateId.ToString() == "2")
                {
                    siteMaster = relativeUrl + "_catalogs/masterpage/" + masterpages[1];
                    systemMaster = relativeUrl + "_catalogs/masterpage/" + masterpages[1];
                }
                else
                {
                    //search - set custom/system master only
                    if ((web.WebTemplateId.ToString() == "90") || (web.WebTemplateId.ToString() == "50"))
                    {
                        siteMaster = relativeUrl + "_catalogs/masterpage/" + masterpages[2];
                    }
                }
            }
            else
            {
                siteMaster = relativeUrl + "_catalogs/masterpage/" + "v4.master";
                systemMaster = relativeUrl + "_catalogs/masterpage/" + "v4.master";
                
                //mettings - set both masters
                if (web.WebTemplateId.ToString() == "2")
                {
                    siteMaster = relativeUrl + "_catalogs/masterpage/" + "MWSDefaultv4.master";
                    systemMaster = relativeUrl + "_catalogs/masterpage/" + "MWSDefaultv4.master";
                }
                else
                {
                    //search - set custom/system master only
                    if ((web.WebTemplateId.ToString() == "90") || (web.WebTemplateId.ToString() == "50"))
                    {
                        siteMaster = relativeUrl + "_catalogs/masterpage/" +"minimal.master";
                    }
                }
            }

            web.MasterUrl = systemMaster;
            web.CustomMasterUrl = siteMaster;
        }

        /// <summary>
        /// This method checks if a specified list exists or not at the specified web site
        /// </summary>
        public static bool ListExists(SPWeb web, string listName)
        {
            return web.Lists.Cast<SPList>().Any(list => string.Equals(list.Title, listName));
        }

        /// <summary>
        /// This method checks in and publishes a specific file
        /// </summary>
        private void PublishFile(SPFile file)
        {
            if (file.Level == SPFileLevel.Checkout) file.CheckIn("", SPCheckinType.MajorCheckIn);
            if (file.Level == SPFileLevel.Draft)
            {
                if (file.DocumentLibrary.EnableModeration) file.Approve("");
                else file.Publish("");
            }
        }

        /// <summary>
        /// This method checks in and publishes all files in a list
        /// </summary>
        private void CheckinCustomList(SPWeb web, string listName)
        {
            if (ListExists(web, listName))
            {
                SPList customthemelist = web.Lists[listName];
                foreach (SPListItem item in customthemelist.Items)
                {
                    SPFile file = web.GetFile(item.Url);
                    PublishFile(file);
                }
            }
        }

        /// <summary>
        /// This method checks in all files in a list from a specific web site, and removes it
        /// </summary>
        private void RemoveList(SPWeb web, string listName)
        {
            CheckinCustomList(web, listName);
            if (ListExists(web, listName))
            {
                SPList customthemelist = web.Lists[listName];
                if (customthemelist != null)
                {
                    customthemelist.Delete();
                }
            }
        }
        
        // Uncomment the method below to handle the event raised after a feature has been installed.
        //public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        //{
        //}

        // Uncomment the method below to handle the event raised before a feature is uninstalled.
        //public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        //{
        //}

        // Uncomment the method below to handle the event raised when a feature is upgrading.
        //public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
        //{
        //}
    }
}
